// 引入express
const express = require("express")
const axios = require("axios")
const qs = require("qs")
const app = express()

const cors = require("cors")

app.use(cors()) //不写匹配路径，代表所有的请求都允许跨域

let cookies = {}
let csrfs = {}

function findSid(cookies) {
  return cookies
    .find(item => item.startsWith("sid"))
    .split(";")
    .find(item => item.startsWith("sid"))
    .split("=")[1]
}

function findCsrf(cookies) {
  return cookies
    .find(item => item.startsWith("bili_jct"))
    .split(";")
    .find(item => item.startsWith("bili_jct"))
    .split("=")[1]
}

function formatCookies(cookies) {
  let str = ""
  cookies.forEach(item => (str += item + "; "))
  return str
}

app.use(express.urlencoded({ extened: false }))

//二维码登录请求
app.post("/qrcode/getLoginInfo", async (req, res) => {
  const proxy = await axios({
    method: "POST",
    url: "https://passport.bilibili.com/qrcode/getLoginInfo",
    headers: { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" },
    data: qs.stringify({ oauthKey: req.body.oauthKey }),
  })

  if (proxy.data.code === 0) {
    const sid = findSid(proxy.headers["set-cookie"])

    cookies["sid-" + sid] = formatCookies(proxy.headers["set-cookie"])
    csrfs["sid-" + sid] = findCsrf(proxy.headers["set-cookie"])

    //让前端把这个sid保存到本地，在发送需要cookie的请求的时候，就带上这个sid，在cookies对象中取出对应的cookie字符串，添加到转发的请求中
    proxy.data.data.sid = sid
    res.send({ ...proxy.data })
  } else {
    res.send({ ...proxy.data })
  }
})

//退出登录请求
app.post("/login/exit/v2", async (req, res) => {
  const _sid = req.query.sid
  let cookie

  cookie = cookies["sid-" + _sid]
  try {
    const proxy = await axios({
      method: "POST",
      headers: cookie && { cookie },
      url: "https://passport.bilibili.com/login/exit/v2",
    })
    res.send(proxy.data)
  } catch ({ message }) {
    res.send({ message })
  }

  delete cookies["sid-" + _sid]
})

//获取二维码登录时所需的二维码url和oauthKey
app.use("/qrcode/getLoginUrl", async (req, res) => {
  //get方法的参数在query对象
  const proxy = await axios({
    method: "GET",
    url: "https://passport.bilibili.com/qrcode/getLoginUrl",
  })

  res.send(proxy.data)
})

//点赞视频
app.post("/web-interface/archive/like", async (req, res) => {
  const _sid = req.query.sid
  let cookie, csrf
  if (_sid) {
    cookie = cookies["sid-" + _sid]
    csrf = csrfs["sid-" + _sid]
  }

  const proxy = await axios({
    url: "https://api.bilibili.com/x/web-interface/archive/like",
    method: "POST",
    headers: cookie
      ? {
          "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
          cookie,
        }
      : { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" },
    body: qs.stringify({
      ...req.body,
      csrf,
    }),
  })
  res.send(proxy.data)
})

//投币视频
app.post("/web-interface/coin/add", async (req, res) => {
  const _sid = req.query.sid
  let cookie, csrf
  if (_sid) {
    cookie = cookies["sid-" + _sid]
    csrf = csrfs["sid-" + _sid]
  }

  const proxy = await axios({
    url: "https://api.bilibili.com/x/web-interface/coin/add",
    method: "POST",
    headers: cookie
      ? {
          "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
          cookie,
        }
      : { "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" },
    body: qs.stringify({
      ...req.body,
      csrf,
    }),
  })
  res.send(proxy.data)
})

app.use("/dynamic_svr", async (req, res) => {
  // console.log(req.url)
  const _sid = req.query.sid
  let cookie
  if (_sid) {
    cookie = cookies["sid-" + _sid]
  }
  try {
    const proxy = await axios({
      method: "GET",
      headers: cookie && { cookie },
      url: "https://api.vc.bilibili.com/dynamic_svr" + req.url,
    })
    res.send(proxy.data)
  } catch ({ message }) {
    res.send({ message })
  }
})

//所有非二维码的get请求都走这个接口,res.url就是路径+查询字符串的完整，直接转发
app.get("/*", async (req, res) => {
  const _sid = req.query.sid
  let cookie
  if (_sid) {
    cookie = cookies["sid-" + _sid]
  }

  // delete req.query.sid

  // console.log( "https://api.bilibili.com/x" + req.url )

  try {
    const proxy = await axios({
      method: "GET",
      headers: cookie && { cookie },
      url: "https://api.bilibili.com/x" + req.url,
      // params: { ...req.query, sid: undefined },
    })
    res.send(proxy.data)
  } catch ({ message }) {
    res.send({ message })
    // console.log( err )
    // res.send(err)
  }
})

app.listen(3333, () => {
  console.log("----------server start 3333----------")
})
